Audit trail for message actions (retry, archive, unarchive)#5570
Draft
ramonsmits wants to merge 14 commits into
Draft
Audit trail for message actions (retry, archive, unarchive)#5570ramonsmits wants to merge 14 commits into
ramonsmits wants to merge 14 commits into
Conversation
Emit a per-message IMessageActionAuditLog.MessageAction for every message actually retried, archived, or unarchived, attributed to the initiating user and correlated to the operation entry via an operation id. - Wire the AuditHeaders stamp/read seam into the async command pipeline; persist the initiating user + operation id on RetryBatch and the Archive/Unarchive operation documents so bulk/group operations resolved by background schedulers (and resumed after restart) stay attributed. - Emit per-message entries at the execution choke points (RetryProcessor staging, MessageArchiver batch loop, and the archive/unarchive/pending handlers) instead of at the API, so each message is logged exactly once when it is actually acted on. - Use the ASP.NET Core request id (HttpContext.TraceIdentifier) as the operation id and return it as a Request-Id response header on all three instances (exposed via CORS) so callers can correlate.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Records every user-initiated retry, archive, and unarchive action as a structured audit entry attributed to the initiating user. Each invocation produces one operation entry (who / what / scope) plus one message entry per message actually acted on. Message entries are emitted at execution time — after the message is really retried or archived — including for bulk/group operations resolved in the background and resumed after a restart. Both entry kinds share an operation id so an operation can be traced through to every message it affected.
Audit output
Entries are written to
audit.json(one ECS-formatted JSON object per line) and to the console, on dedicated log categoriesServiceControl.Audit(operations) andServiceControl.Audit.Messages(per-message), so the audit stream can be shipped to a SIEM independently of the operational log. Allowed actions log at Information, failures at Warning.Example — retrying all messages (operation entry followed by one entry per staged message):
{"@timestamp":"2026-07-03T12:18:54.04Z","event":{"kind":"event","category":["configuration"],"type":["change"],"action":"error:messages:retry","outcome":"success"},"user":{"id":"d4c3b2a1-…","name":"alice@example.com"},"servicecontrol":{"permission":"error:messages:retry","scope":"all","operation":{"id":"0HN7GK3M8QABC:00000042"}}} {"@timestamp":"2026-07-03T12:18:54.08Z","event":{"kind":"event","category":["configuration"],"type":["change"],"action":"error:messages:retry","outcome":"success"},"user":{"id":"d4c3b2a1-…","name":"alice@example.com"},"servicecontrol":{"permission":"error:messages:retry","scope":"all","message":{"id":"3f2504e0-4f89-11d3-9a0c-0305e82c3301"},"operation":{"id":"0HN7GK3M8QABC:00000042"}}}event.typeischangefor retry/unarchive anddeletionfor archive;outcomeissuccessorfailure.scope(single/batch/queue/endpoint/all/group/range), and where applicableresourceandcount; message entries carrymessage.id. Null-valued fields are omitted.Settings
LogPath— directory foraudit.json(alongside the operational log). In containers the audit trail goes to the console only (no file).LogLevel— controls operational verbosity only. The audit trail is always captured from Information upward, so loweringLogLevelnever drops audit entries.Correlation
Each operation's id is the ASP.NET request id (
TraceIdentifier) and is returned on every response as theRequest-Idheader (exposed via CORS on all instances). The same value appears inservicecontrol.operation.idon the operation entry and every per-message entry, so a caller can correlate a single API call to each affected message and to the request's other logs.